package com.vdong.trade.trading.service.dubbo;

import com.alibaba.fastjson.JSON;
import com.vdong.trade.trading.common.exception.ProcessException;
import com.vdong.trade.trading.entity.dto.param.AmountParamDTO;
import com.vdong.trade.trading.entity.dto.param.OrderTradingPramDTO;
import com.vdong.trade.trading.entity.mo.AmountMO;
import com.vdong.trade.trading.entity.mo.OrderMO;
import com.vdong.trade.trading.entity.mo.TradingMO;
import com.vdong.trade.trading.facade.AmountFacade;
import com.vdong.trade.trading.facade.enums.SettlementStatusEnum;
import com.vdong.trade.trading.facade.enums.UserTypeEnum;
import com.vdong.trade.trading.respository.AmountMORepository;
import com.vdong.trade.trading.service.AmountService;
import lombok.extern.slf4j.Slf4j;
import org.lamb.framework.common.remote.FacadeResult;
import org.lamb.framework.common.util.BigDecimalUtil;
import org.lamb.framework.common.util.FacadeResultUtils;
import org.lamb.framework.common.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

import static com.vdong.trade.trading.common.enums.ProcessExceptionEnum.EB00000003;
import static com.vdong.trade.trading.common.enums.ProcessExceptionEnum.EB00000004;
import static com.vdong.trade.trading.common.enums.ProcessExceptionEnum.EB00000005;

/**
 * @author zhoulongbiao
 * @Date 2018/12/18 19:16
 */
@Service
@Slf4j
@com.alibaba.dubbo.config.annotation.Service
public class AmountFacadeImpl implements AmountFacade {

    @Resource
    private AmountMORepository amountMORepository;

    @Autowired
    private AmountService amountService;

    @Override
    @Transactional
    public String updateUserAmount(String param) {
        log.info("updateUserAmount,入参为:[{}]", param);
        OrderTradingPramDTO paramDTO = JSON.parseObject(param, OrderTradingPramDTO.class);
        if (StringUtil.hasBlank(paramDTO)) {
            return FacadeResultUtils.failFacadeBeanToString("传入参数不存在");
        }
        AmountMO pushAmount = amountMORepository.selectAmountByEntity(AmountMO.builder().userId(paramDTO.getPusherId())
                .userType(UserTypeEnum.PUSHER.getValue().toString()).build());
        if (StringUtil.hasBlank(pushAmount)) throw new ProcessException(EB00000003);

        AmountMO companyAmount = amountMORepository.selectAmountByEntity(AmountMO.builder().userId(paramDTO.getCompanyId())
                .userType(UserTypeEnum.COMPANY.getValue().toString()).build());
        if (StringUtil.hasBlank(companyAmount)) throw new ProcessException(EB00000003);

        AmountMO merchantAmount = amountMORepository.selectAmountByEntity(AmountMO.builder().userId(paramDTO.getMerchantId())
                .userType(UserTypeEnum.MERCHANT.getValue().toString()).build());
        if (StringUtil.hasBlank(merchantAmount)) throw new ProcessException(EB00000003);

        //增加账户未结算金额
        pushAmount.setSettlementAmount(BigDecimalUtil.add(String.valueOf(pushAmount.getSettlementAmount()),
                String.valueOf(paramDTO.getPusherAnticipatedIncomeAmount())));
        int pushRow = amountMORepository.updateAmountById(pushAmount);
        if (pushRow < 1) throw new ProcessException(EB00000004);

        companyAmount.setSettlementAmount(BigDecimalUtil.add(String.valueOf(companyAmount.getSettlementAmount()),
                String.valueOf(paramDTO.getPlatformAnticipatedIncomeAmount())));
        int companyRow = amountMORepository.updateAmountById(pushAmount);
        if (companyRow < 1) throw new ProcessException(EB00000004);

        merchantAmount.setSettlementAmount(BigDecimalUtil.add(String.valueOf(merchantAmount.getSettlementAmount()),
                String.valueOf(paramDTO.getProductDistributionAmount())));
        int merchantRow = amountMORepository.updateAmountById(pushAmount);
        if (merchantRow < 1) throw new ProcessException(EB00000004);

        return FacadeResultUtils.succFacadeBeanToString(FacadeResult.buildSucc());
    }

    @Override
    @Transactional
    public String updatePusherAndMerchantAmount(String param) {
        log.info("updatePusherAndMerchantAmount,入参为:[{}]", JSON.toJSONString(param));
        List<OrderTradingPramDTO> orderTradingPramDTOS = JSON.parseArray(param, OrderTradingPramDTO.class);
        for (OrderTradingPramDTO mo : orderTradingPramDTOS) {
            //推客
            AmountMO pusherAmount = amountMORepository.selectAmountById(AmountParamDTO.builder().
                    userId(mo.getPusherId()).userType(UserTypeEnum.PUSHER.getValue().toString()).build());
            if (StringUtil.hasBlank(pusherAmount)) throw new ProcessException(EB00000005);
            //减少未结算 增加可提现
            int pusherRow = amountMORepository.updateSettlementByParam(AmountMO.builder()
                    .balance(mo.getPusherAnticipatedIncomeAmount()).userId(pusherAmount.getUserId())
                    .userType(UserTypeEnum.PUSHER.getValue().toString()).build());
            if (pusherRow < 1) throw new ProcessException(EB00000004);
            //商户
            AmountMO merchantAmount = amountMORepository.selectAmountById(AmountParamDTO.builder().
                    userId(mo.getMerchantId()).userType(UserTypeEnum.MERCHANT.getValue().toString()).build());
            if (StringUtil.hasBlank(merchantAmount)) throw new ProcessException(EB00000005);
            //减少未结算 增加可提现
            int merchantRow = amountMORepository.updateSettlementByParam(AmountMO.builder()
                    .balance(mo.getProductDistributionAmount()).userId(merchantAmount.getUserId())
                    .userType(UserTypeEnum.MERCHANT.getValue().toString()).build());
            if (merchantRow < 1) throw new ProcessException(EB00000004);
        }
        return FacadeResultUtils.succFacadeBeanToString(FacadeResult.buildSucc());
    }

    @Override
    public String insertUserAmount(String param) throws Exception {
        log.info("AmountFacade新增用户资金账户入参:[{}]", param);
        if (StringUtil.hasBlank(param)) {
            return JSON.toJSONString(FacadeResult.buildFail("入参不能为空!"));
        }
        AmountParamDTO amountParamDTO = JSON.parseObject(param, AmountParamDTO.class);
        if (StringUtil.hasBlank(amountParamDTO.getUserId(), amountParamDTO.getUserType())) {
            return JSON.toJSONString(FacadeResult.buildFail("用户userId或userType不能为空!"));
        }
        Optional<String> result = amountService.insertUserAmount(amountParamDTO);
        return result.map(s -> JSON.toJSONString(FacadeResult.buildFail(s)))
                .orElseGet(() -> JSON.toJSONString(FacadeResult.buildSucc()));
    }
}
